package com.soxing.braindata.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.soxing.braindata.common.config.SystemConfig;
import com.soxing.braindata.common.util.WebHelper;
import com.soxing.braindata.dao.entity.UserInfo;
import com.soxing.braindata.dao.entity.UserInfoExt;
import com.soxing.braindata.dao.service.IUserInfoExtService;
import com.soxing.braindata.domain.constants.SystemConstant;
import com.soxing.braindata.domain.vo.ChangePasswordVo;
import com.soxing.braindata.domain.vo.UserVo;
import com.soxing.braindata.service.manager.IUserManager;
import com.soxing.common.utils.response.WebResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;

@Slf4j
@RestController
@RequestMapping("/login")
@Api(value = "用户登录", tags = {"用户登录"})
public class LoginController {



    @Resource
    private IUserInfoExtService userInfoExtService;
    @Resource
    private IUserManager userManager;

    @Resource
    private SystemConfig systemConfig;

    @PostMapping("/land")
    @ApiOperation(value = "登录验证")
    public WebResponse<UserVo> land(@RequestBody UserVo user, HttpServletRequest request) {
        String userNum = user.getUserNum();
        String userPwd = user.getUserPwd();
//        WebResponse<UserVo> response = new WebResponse<>();
//        response.setData(user);
        if (userNum == null || userPwd == null) {
            log.error("userNum或userPwd为空");
            return WebResponse.fail("登录验证失败");
        }
        UserInfoExt userInfoExt = userInfoExtService.getOne(new LambdaQueryWrapper<UserInfoExt>().eq(UserInfoExt::getUserNum, userNum));
        if (userInfoExt == null) {
            log.error("{}不是管理员账号", userNum);
            return WebResponse.fail("无登录权限,请联系管理员");
        }
        // 登录失败次数限制
        Date lockTime = userInfoExt.getLockTime();
        if (lockTime != null) {
            Instant dbInstant = lockTime.toInstant();
            Instant nowInstant = Instant.now();
            Duration duration = Duration.between(dbInstant, nowInstant);
            if (duration.compareTo(Duration.ofMinutes(15)) > 0) {
//            if (duration.compareTo(Duration.ofSeconds(15)) > 0) {
                userInfoExt.setLockTime(null);
                userInfoExt.setLoginAttempts(0);
            } else {
                int attempts = userInfoExt.getLoginAttempts();
                if (attempts >= 5) {
                    return WebResponse.fail("登录失败次数达上限，请15分钟后重试");
                }
            }

        }
        if (!userPwd.equals(userInfoExt.getUserPwd())) {
            updateFailAttempts(userInfoExt);
            log.error("{}密码不正确", userNum);
            return WebResponse.fail("登录失败");
        }
        UserVo userVo = userManager.getUserVo(userNum);
        if (userVo == null) {
            log.error("{}未获取到userVo信息", userNum);
            return WebResponse.fail("系统异常");
        }
        request.getSession().setAttribute(SystemConstant.LOGIN_USER, userVo);
        return WebResponse.success(userVo);
    }

    private void updateFailAttempts(UserInfoExt userInfoExt) {
//        UserInfoExt userInfoExt = userInfoExtService.getOne(new LambdaQueryWrapper<UserInfoExt>().eq(UserInfoExt::getUserNum, userNum));
        if (userInfoExt != null) {
            if(userInfoExt.getLoginAttempts() == null) {userInfoExt.setLoginAttempts(0);}
            int attempts = userInfoExt.getLoginAttempts() + 1;
            if (attempts >= 5) {
                userInfoExt.setAccountNonLocked(false);
                userInfoExt.setLockTime(new Date());
            }
            userInfoExt.setLoginAttempts(attempts);
            LambdaUpdateWrapper<UserInfoExt> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(UserInfoExt::getUserNum,userInfoExt.getUserNum());
            updateWrapper.set(UserInfoExt::getLockTime, userInfoExt.getLockTime());
            userInfoExtService.update(userInfoExt,updateWrapper);
        }
    }

    private void resetFailAttempts(String userNum) {
        UserInfoExt userInfoExt = userInfoExtService.getOne(new LambdaQueryWrapper<UserInfoExt>().eq(UserInfoExt::getUserNum, userNum));
        if (userInfoExt != null) {
            userInfoExt.setLoginAttempts(0);
            userInfoExt.setAccountNonLocked(true);
            userInfoExt.setLockTime(null);
            userInfoExtService.save(userInfoExt);
        }
    }

    @GetMapping("/logout")
    public WebResponse logout(HttpServletRequest request, HttpServletResponse response)
    {

        HttpSession session = request.getSession();
        if(session!=null)
        {
            session.invalidate();
        }
        Cookie cookie = new Cookie(SystemConstant.LOGIN_USER, null);  //让cookie失效这样写也没什么用 应该session.invalidate()
        cookie.setMaxAge(0);
        response.addCookie(cookie);
        return WebResponse.success();
    }


    @PostMapping("/changePassword")
    @ApiOperation(value = "修改密码")
    public WebResponse changePassWord(@RequestBody ChangePasswordVo changePasswordVo)  //之后加入通过session验证权限限制的操作
    {
        UserVo userVo=WebHelper.getUserInfo();
        if(userVo==null)
        {
            return WebResponse.fail("修改失败");
        }
        if(changePasswordVo.getUserNum()==null)
        {
            return WebResponse.fail("修改失败");
        }
        if(!changePasswordVo.getUserNum().equals(userVo.getUserNum()))
        {
            return WebResponse.fail("修改失败");
        }
        UserInfoExt userInfoExt = userInfoExtService.getOne(new LambdaQueryWrapper<UserInfoExt>().eq(UserInfoExt::getUserNum, userVo.getUserNum()));
        if(!changePasswordVo.getUserPwd().equals(userInfoExt.getUserPwd()))
        {
            return WebResponse.fail("原密码错误");
        }
        userInfoExt.setUserPwd(changePasswordVo.getNewPwd());
        userInfoExtService.update(userInfoExt,new LambdaQueryWrapper<UserInfoExt>().eq(UserInfoExt::getUserNum,userInfoExt.getUserNum()));
        return WebResponse.success("修改成功");
    }

    @GetMapping("/resetPassWord")
    @ApiOperation(value = "重置密码")
    public WebResponse resetPassWord(@RequestParam String userNum)  //之后加入通过session验证权限限制的操作
    {

        if(systemConfig.isNeedLogin())
        {
            UserVo userVo=WebHelper.getUserInfo();
            if(userVo.getUserType()!=0)
            {
                return WebResponse.fail("无权限");

            }

        }
        UserInfoExt userInfoExt = userInfoExtService.getOne(new LambdaQueryWrapper<UserInfoExt>().eq(UserInfoExt::getUserNum, userNum));
        userInfoExt.setUserPwd("8ae01bd48fdb918855763baac63b19ac");//都默认为BHPeeg123!
        userInfoExtService.update(userInfoExt, new LambdaQueryWrapper<UserInfoExt>().eq(UserInfoExt::getUserNum,userInfoExt.getUserNum()));
        return WebResponse.success("修改成功");
    }

}
